package com.fingard.dsp.bank.directbank.cmbc02;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.alibaba.fastjson.JSON;
import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.FailCode;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.ISinglePay;
import com.fingard.dsp.bank.directbank.pab02.Util.api.utils.StringUtil;
import com.fingard.dsp.bank.reqrespobj.single.ReqQrySingle;
import com.fingard.dsp.bank.reqrespobj.single.ReqQrySingleBat;
import com.fingard.dsp.bank.reqrespobj.single.ReqSingle;
import com.fingard.dsp.bank.reqrespobj.single.ReqSingleBat;
import com.fingard.dsp.bank.reqrespobj.single.RetAtsSingle;
import com.fingard.dsp.bank.reqrespobj.single.RetAtsSingleBat;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.net.ConnState;
import com.fingard.text.StringHelper;

/**
 * 民生收付易单笔支付
 * 
 * @author Cruise
 * @date 2019/3/12
 */
public class CMBC02SinglePay extends CMBC02Base implements ISinglePay {
	@SuppressWarnings("unchecked")
	@Override
	public RetAtsSingle d_1908_SglPay(ReqSingle p_req1908) throws Exception {
		RetAtsSingle retAts = new RetAtsSingle(p_req1908.reqHeader);
		RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
		tmpRetDetail.reqSeqID = p_req1908.singleDetail.askNumber;
		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_req1908.singleDetail.payAct, "");
			if (actItem == null) {
				tmpRetDetail.respCode = "0";
				tmpRetDetail.respInfo = "未找到账号[" + p_req1908.singleDetail.payAct + "]商户配置信息";
				tmpRetDetail.reqSeqID = p_req1908.singleDetail.askNumber;
				tmpRetDetail.transState = PaymentState.FAIL_Payment;
				tmpRetDetail.payInfoCode = FailCode.E9981;
				retAts.writeRetDetail(tmpRetDetail);
				return retAts;
			}
			String cardtype = "";
			String version = "v1.0";// 版本号 version String 16 Y
			String source = "PC";// 发起来源 source String 16 Y
			String merchantNum = actItem.merchantId;// 商户编号 merchantNum String
			Date timeNow = new Date();
			String transDate = Format.Date8Format.format(timeNow);// 交易日期
			String transTime = Format.Time9Format.format(timeNow);// 交易时间
			String transCode = "PAY_T005";// 交易编码 transCode String 16 Y 交易编码
			String securityType = "SM203";// 安全类型 securityType String 16 Y
			String reserve1 = "";// 备用字段1 reserve1 String 16 N 一般备用字段
			String reserve2 = "";// 备用字段2 reserve2 String 32 N 一般备用字段
			String reserve3 = "";// 备用字段3 reserve3 String 64 N 一般备用字段
			String reserve4 = "";// 备用字段4 reserve4 String 128 N 一般备用字段
			String reserve5 = "";// 备用字段5 reserve5 String 256 N 一般备用字段
			String reserveJson = "";// 通用备用字段 reserveJson String 512 N
			// 组织请求业务报文
			String defaultTradeType = "30010002";// 交易子类型 defaultTradeType
			String contractId = actItem.getBusCode("singlePay");// 签约编码
			String subject = "";// 交易标题 subject String 64 N
			String body = "";// 交易详情 body String 256 N
			String postscript = "";// 摘要 postscript String 300 N
			String summary = p_req1908.singleDetail.memo;// 备注 summary String
			String currencyCode = "RMB";// 交易币种 currencyCode String 8 Y
			String amount = p_req1908.singleDetail.payAmount;// 交易金额 amount
			String bizType = "2006";// 产品类型 bizType String 16 Y
			String orderId = "";// 订单号 orderId String 20 N

			String payeeAccType = "";// 收款账户类型 payeeAccType String 1 Y
			String cardType = p_req1908.singleDetail.cardType;
			if (StringHelper.hasAnyChar(cardType)) {
				payeeAccType= convertCardTypeMapping(cardType);//不上送，默认为借记卡
			}else {
				payeeAccType="1";
			}
			if(!StringHelper.hasAnyChar(payeeAccType)){//默认为借记卡
				payeeAccType="1";
			}
			String payeePartyId = "305100000013";// 收款账户开户行
			String payeePartyName = p_req1908.singleDetail.cnapsName;// 收款行名
			String payeeAccNo = p_req1908.singleDetail.recAct;// 收款人账号
			String payeeAccName = p_req1908.singleDetail.recName;// 收款人户名
			String payeeCertType=convertCertTypeToBank(p_req1908.singleDetail.certType);
			String payeeCertNo = p_req1908.singleDetail.certNum;// 收款人证件号码
			String payeeMobile = p_req1908.singleDetail.cellPhone;// 收款人手机号
			String notifyUrl = "";// 后台通知地址 notifyUrl String 256 N
			String reqReserved = "";// 请求方保留域 reqReserved String 256 N
			String riskRateInfo = "";// 风险信息域 riskRateInfo String 256 N
			String userMac = "";// 终端信息域 userMac String 256 N
			String reserved = "";// 保留域 reserved String 256 N
			// 发送给银行的报文
			Map<String, String> messagetoBank = new HashMap<String, String>();
			messagetoBank.put("version", version);
			messagetoBank.put("source", source);
			messagetoBank.put("merchantNum", merchantNum);
			String merchantSeq = p_req1908.singleDetail.askNumber;
			boolean padSingleSeq50 = getBankConfig().getValueAsBool("padSingleSeq50");
			this.WriteBankLogLn("padSingleSeq50:"+padSingleSeq50);
			if(padSingleSeq50){
				merchantSeq = actItem.merchantId+"_"+p_req1908.singleDetail.askNumber+"_";
				merchantSeq = StringHelper.padByByte(merchantSeq, this.getCharset(reqHeader.transType), 50, '0', 'R');
			}
			messagetoBank.put("merchantSeq", merchantSeq);
			messagetoBank.put("transDate", transDate);
			messagetoBank.put("transTime", transTime);
			messagetoBank.put("transCode", transCode);
			messagetoBank.put("securityType", securityType);
			messagetoBank.put("reserve1", reserve1);
			messagetoBank.put("reserve2", reserve2);
			messagetoBank.put("reserve3", reserve3);
			messagetoBank.put("reserve4", reserve4);
			messagetoBank.put("reserve5", reserve5);
			messagetoBank.put("reserveJson", reserveJson);
			messagetoBank.put("defaultTradeType", defaultTradeType);// 交易子类型
			messagetoBank.put("contractId", contractId);// 签约编码 contractId
			messagetoBank.put("subject", subject);// 交易标题 subject String 64 N
			messagetoBank.put("body", body);
			messagetoBank.put("postscript", postscript);
			messagetoBank.put("summary", summary);
			messagetoBank.put("currencyCode", currencyCode);
			messagetoBank.put("amount", amount);
			messagetoBank.put("bizType", bizType);
			messagetoBank.put("orderId", orderId);
			messagetoBank.put("payeeAccType", payeeAccType);
			messagetoBank.put("payeePartyId", payeePartyId);
			messagetoBank.put("payeePartyName", payeePartyName);
			messagetoBank.put("payeeAccNo", payeeAccNo);
			messagetoBank.put("payeeAccName", payeeAccName);
			messagetoBank.put("payeeCertType", payeeCertType);
			messagetoBank.put("payeeCertNo", payeeCertNo);
			messagetoBank.put("payeeMobile", payeeMobile);
			messagetoBank.put("notifyUrl", notifyUrl);
			messagetoBank.put("reqReserved", reqReserved);
			messagetoBank.put("riskRateInfo", riskRateInfo);
			messagetoBank.put("userMac", userMac);
			messagetoBank.put("reserved", reserved);

			Map<String, String> submitMap = new HashMap<String, String>();
			Map<String, String> busiMap = new HashMap<String, String>();

			splidReqMap(messagetoBank, submitMap, busiMap);
			submitMap.put("businessContext", encodeMsgToString(p_req1908.singleDetail.payAct, busiMap));

			String message = submitMap.toString();
			WriteBankLogLn("发送给银行的报文：" + message);

			String tmpUrl = bankFront.getUrl("Pay");
			String[] tmpStrRet = sendToBank(submitMap, tmpUrl);
			if (tmpStrRet[0].length() == 0) {
				WriteBankLogLn("银行返回的报文：" + tmpStrRet[1]);
				Map<String, String> reMap = (Map<String, String>) JSON.parse(tmpStrRet[1].toString());
				WriteBankLogLn("解析后银行返回的报文map形式：" + reMap);
				WriteBankLogLn("解析后银行返回的报文：" + reMap.toString());
				String gateReturnType = reMap.get("gateReturnType");
				String code = reMap.get("gateReturnCode");
				String respInfo = reMap.get("gateReturnMessage");
				if ("S".equals(gateReturnType)) {
					String returnMessage = reMap.get("businessContext");
					WriteBankLogLn("银行返回报文中的businessContext：" + returnMessage);
					String returnbody = decodeMsgToString(p_req1908.singleDetail.payAct, returnMessage);
					WriteBankLogLn("解密结果：" + returnbody);
					Map<String, String> str = (Map<String, String>) JSON.parse(returnbody.toString());
					String busiCode = str.get("busiCode");
					String busiMsg = str.get("busiMsg");
					tmpRetDetail.respCode = "0";
					tmpRetDetail.payInfoCode = busiCode;
					tmpRetDetail.respInfo = busiMsg;
					tmpRetDetail.transState = busiCode;
				} else if ("E".equals(gateReturnType)) {
					tmpRetDetail.respCode = "0";
					tmpRetDetail.respInfo = respInfo;
					tmpRetDetail.payInfoCode = code;
					tmpRetDetail.transState = code;
				} else {
					tmpRetDetail.respCode = "-1";
					tmpRetDetail.respInfo = respInfo;
				}
			} else if (tmpStrRet[0].equals(ConnState.FAIL)) {
				tmpRetDetail.respCode = "0";
				tmpRetDetail.respInfo = tmpStrRet[1];
				tmpRetDetail.reqSeqID = p_req1908.reqHeader.reqSeqID;
				tmpRetDetail.transState = PaymentState.FAIL_Batch;
				tmpRetDetail.payInfoCode = tmpStrRet[0];
			} else {
				tmpRetDetail.respCode = "-1";
				tmpRetDetail.respInfo = tmpStrRet[1];
			}

		} catch (Exception ex) {
			ex.printStackTrace();
			tmpRetDetail.respCode = "-1";
			tmpRetDetail.respInfo = ex.getMessage();
			WriteBankLogLn(ex);
		}
		
		retAts.writeRetDetail(tmpRetDetail);
		return retAts;
	}

	@SuppressWarnings("unchecked")
	@Override
	public RetAtsSingle d_1944_QrySglPay(ReqQrySingle p_req1944) throws Exception {
		RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
		RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_req1944.payAct, "");
			if (actItem == null) {
				tmpRetDetail.respCode = "-1";
				tmpRetDetail.respInfo = "未找到账号[" + p_req1944.payAct + "]商户配置信息!";
				retAts.writeRetDetail(tmpRetDetail);
				return retAts;
			}
			// 组装请求报文
			String version = "v1.0";// 版本号 version String 16 Y
			String source = "PC";// 发起来源 source String 16 Y
			String merchantNum = actItem.merchantId;// 商户编号 merchantNum String
			String merchantSeq = genMerchantSeq(merchantNum);// 商户流水 merchantSeq
			Date timeNow = new Date();
			String transDate = Format.Date8Format.format(timeNow);// 交易日期
			String transTime = Format.Time9Format.format(timeNow);// 交易时间
			String transCode = "PAY_Q001";// 交易编码 transCode String 16 Y 交易编码
			String securityType = "SM203";// 安全类型 securityType String 16 Y
			String reserve1 = "";// 备用字段1 reserve1 String 16 N 一般备用字段
			String reserve2 = "";// 备用字段2 reserve2 String 32 N 一般备用字段
			String reserve3 = "";// 备用字段3 reserve3 String 64 N 一般备用字段
			String reserve4 = "";// 备用字段4 reserve4 String 128 N 一般备用字段
			String reserve5 = "";// 备用字段5 reserve5 String 256 N 一般备用字段
			String reserveJson = "";// 通用备用字段 reserveJson String 512 N
			// 组装业务报文
			String contractId = actItem.getBusCode("singlePay");// 签约编码
			String defaultTradeType = "30010002";// 交易子类型 defaultTradeType
			String orgMerchantSeq = p_req1944.askNumber;// 商户流水号 orgMerchantSeq
			if(this.getBankConfig().getValueAsBool("padSingleSeq50")){
				orgMerchantSeq = actItem.merchantId+"_"+p_req1944.askNumber+"_";
				orgMerchantSeq = StringHelper.padByByte(orgMerchantSeq, this.getCharset(reqHeader.transType), 50, '0', 'R');
			}
			String reserved = "";// 保留域 reserved String 256 N
			// 发送给银行的报文
			Map<String, String> messagetoBank = new HashMap<String, String>();
			messagetoBank.put("version", version);
			messagetoBank.put("source", source);
			messagetoBank.put("merchantNum", merchantNum);
			messagetoBank.put("merchantSeq", merchantSeq);
			messagetoBank.put("transDate", transDate);
			messagetoBank.put("transTime", transTime);
			messagetoBank.put("transCode", transCode);
			messagetoBank.put("securityType", securityType);
			messagetoBank.put("reserve1", reserve1);
			messagetoBank.put("reserve2", reserve2);
			messagetoBank.put("reserve3", reserve3);
			messagetoBank.put("reserve4", reserve4);
			messagetoBank.put("reserve5", reserve5);
			messagetoBank.put("reserveJson", reserveJson);
			messagetoBank.put("contractId", contractId);
			messagetoBank.put("defaultTradeType", defaultTradeType);
			messagetoBank.put("orgMerchantSeq", orgMerchantSeq);
			messagetoBank.put("reserved", reserved);
			Map<String, String> submitMap = new HashMap<String, String>();
			Map<String, String> busiMap = new HashMap<String, String>();
			splidReqMap(messagetoBank, submitMap, busiMap);
			submitMap.put("businessContext", encodeMsgToString(p_req1944.payAct, busiMap));
			String message = submitMap.toString();
			WriteBankLogLn("发送给银行的报文：" + message);
			String tmpUrl = bankFront.getUrl("Query");
			String[] tmpStrRet = sendToBank(submitMap, tmpUrl);
			if (tmpStrRet[0].length() == 0) {
				WriteBankLogLn("银行返回的报文：" + tmpStrRet[1]);
				Map<String, String> reMap = (Map<String, String>) JSON.parse(tmpStrRet[1].toString());
				WriteBankLogLn("解析后银行返回的报文map形式：" + reMap);
				WriteBankLogLn("解析后银行返回的报文：" + reMap.toString());
				String gateReturnType = reMap.get("gateReturnType");
				String respInfo = reMap.get("gateReturnMessage");
				if ("S".equals(gateReturnType)) {
					String returnMessage = reMap.get("businessContext");
					WriteBankLogLn("银行返回报文中的businessContext：" + returnMessage);
					String returnbody = decodeMsgToString(p_req1944.payAct, returnMessage);
					WriteBankLogLn("解密结果：" + returnbody);
					Map<String, String> str = (Map<String, String>) JSON.parse(returnbody.toString());
					String busiType = str.get("busiType");
					String busiCode = str.get("busiCode");
					String busiMsg = str.get("busiMsg");
                    if ("S".equals(busiType)) {
                        String returnorgMerchantSeq = str.get("orgMerchantSeq");
                        String platSeq = str.get("platSeq");
                        String amount = str.get("amount");
                        String status = str.get("status");
                        tmpRetDetail.respCode = "0";
                        tmpRetDetail.transState = busiCode+ "+" +status;
                        tmpRetDetail.outTransID = platSeq;
                        tmpRetDetail.transAmt = amount;
                        reserved = str.get("reserved");
                        if(!StringUtil.isNull(reserved)&&reserved.length()>7&&reserved.indexOf("|")>8){
                            tmpRetDetail.respInfo = reserved.substring(reserved.indexOf("errMsg")+7,reserved.indexOf("|"));
                            tmpRetDetail.payInfoCode = tmpRetDetail.respInfo;
                        }
                        if(returnorgMerchantSeq.equals(orgMerchantSeq)){
                            tmpRetDetail.reqSeqID = p_req1944.askNumber;
                        }else{
                            tmpRetDetail.respCode = "-1";
                            tmpRetDetail.respInfo = "响应流水号"+returnorgMerchantSeq+"与请求"+orgMerchantSeq+"不相符";
                        }
                    } else	if ("E".equals(busiType) && busiMsg.contains("数据库查询无记录")&&canBeNotExist(p_req1944, tmpRetDetail, 30)) {
						tmpRetDetail.respCode = "0";
						tmpRetDetail.respInfo = "数据库查询无记录";
						tmpRetDetail.transState =busiCode+"+"+busiMsg;
						tmpRetDetail.payInfoCode =busiCode;
						tmpRetDetail.reqSeqID = p_req1944.askNumber;

					} else {
						tmpRetDetail.respCode = "-1";
						tmpRetDetail.respInfo = busiMsg;
					}
				} else {
					tmpRetDetail.respCode = "-1";
					tmpRetDetail.respInfo = respInfo;
				}
			} else {
				tmpRetDetail.respCode = "-1";
				tmpRetDetail.respInfo = tmpStrRet[1];
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			tmpRetDetail.respCode = "-1";
			tmpRetDetail.respInfo = ex.getMessage();
			WriteBankLogLn(ex);
		}
		retAts.writeRetDetail(tmpRetDetail);
		return retAts;
	}

	@Override
	public RetAtsSingleBat d_1908BAT_SglBatPay(ReqSingleBat p_req1908BAT) throws Exception {
		return null;
	}

	@Override
	public RetAtsSingleBat d_1944BAT_QrySglBatPay(ReqQrySingleBat p_req1944BAT) throws Exception {
		return null;
	}
}
